import 'dart:math';

import 'package:dartkit/dartkit.dart';

class Generate {
  /// 通过自定义的字符集，生成任意长度的字符串
  static String custom(String alphabet, int length) {
    // 确保length大于0,否则报错
    if (length <= 0) throw ArgumentError('长度必须>=0');

    // 设定空的初始id
    String result = '';

    // 在变量id中,循环添加${length}个字符
    for (int i = 0; i < length; i++) {
      // 取随机字符
      final random = Random();
      final randomIndex = random.nextInt(alphabet.length);
      final randomChar = alphabet[randomIndex];

      // 在id的末尾添加字符
      result += randomChar;
    }

    // 返回生成好的id
    return result;
  }

  /// 纯数字字符集，通常用于生成短信安全码
  static String number(int length) => custom("0123456789", length);

  /// 字母字符集，通常用于生成id、序列号
  static String letter(int length) => custom(
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", length);

  /// 小写字符集，通常用于大小写不敏感的id、序列号（比如Linux的文件名）
  static String letterLowercase(int length) =>
      custom("abcdefghijklmnopqrstuvwxyz0123456789", length);

  /// 传入某个生成的方法，以及一个已有项目的列表
  /// 生成一个不重复的值
  static T unique<T>(Iterable<T> exists, T Function() generate) {
    // 先生成一个值
    var result = generate();
    int count = 0;
    // 只要值和已存在的内容冲突，则重新生成
    // 直到不重复为止
    // 最多尝试100次，如果100次都没有避免重复，则认为无法生成，以报错结束
    while (exists.contains(result)) {
      result = generate();
      count++;
      const max = 1000;
      if (count > max) {
        throw Bug("尝试超过最大次数$max");
      }
    }
    return result;
  }
}
